#pragma once


#include <chrono>
#include <cstdint>
#include <thread>

namespace good_cptl
{
class Sleeper
{
private:
  const std::chrono::nanoseconds delta_;
  uint32_t spin_count_;

  static constexpr uint32_t kMaxActiveSpin = 4000;
public:
  static constexpr std::chrono::nanoseconds kMinYieldingSleep =
      std::chrono::microseconds(500);
  constexpr Sleeper() noexcept
   : delta_(kMinYieldingSleep)
   , spin_count_(0)
  {}
  explicit Sleeper(std::chrono::nanoseconds d) noexcept
   : delta_(d)
   , spin_count_(0)
  {}

  void wait() noexcept
  {
    if (spin_count_ < kMaxActiveSpin) {
      ++spin_count_;
      // x86 平台下的 pause 指令（减少 CPU 竞争）
      // asm volatile("pause");
    } else {
      std::this_thread::sleep_for(delta_);
    }
  }
};
}